﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;
using System.Threading;
using UnityEngine;
public class TcpServerCore
{

    /// <summary>
    /// 服务器Socket
    /// </summary>
    private Socket tcpServer;
    private string ip;
    private int port;
    /// <summary>
    /// 服务器是否正在运行
    /// </summary>
    private bool isRun = false;
    /// <summary>
    /// 所有的连接代理
    /// </summary>
    private List<ClientBase> allClients = new List<ClientBase>();

    //private TcpServerModule serverModule;
    private bool isPacketDecode = true;

    //互斥锁
    private static readonly Mutex mux = new Mutex();


    /// <summary>
    /// TODO 获取变量，后期删除
    /// </summary>
    /// <param name="clientNum"></param>
    public void GetParas(ref int clientNum)
    {
        clientNum = allClients.Count;
    }
    /// <summary>
    /// 启动服务器
    /// </summary>
    public bool StartServer(string ip, string port, bool isPacketDecode, Action<CoreEvent> ceEvent)
    {
        if (isRun)
        {
            CoreEvent cevent = new CoreEvent();
            cevent.eventType = NetEventType.SS_SERVER_ALREADY_EXISTS;
            cevent.log = string.Format("[{0}:{1}]服务器已经启动", this.ip, this.port);
            NetCore.AddEvent(cevent);
            return false;
        }
        this.isPacketDecode = isPacketDecode;
        EndPoint iep = null;
        CoreEvent ce = new CoreEvent();
        if (!NetCore.VerifyEndPoint(ip, port, ref iep, ref ce))
        {
            NetCore.AddEvent(ce);
            return false;
        }
            

        mux.WaitOne();
        if (tcpServer == null)
            tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        try
        {
            tcpServer.Bind(iep);
            tcpServer.Listen(2);
            isRun = true;
            //开始监听客户端连接
            tcpServer.BeginAccept(AcceptCb, null);
            mux.ReleaseMutex();

            CoreEvent cevent = new CoreEvent();
            cevent.eventType = NetEventType.SS_SERVER_START_SUCCESS;
            cevent.log = string.Format("[{0}:{1}]服务器启动成功!", ip, port);
            NetCore.AddEvent(cevent);

            this.ip = ip;
            this.port = int.Parse(port);
            //初始化回调
            return true;
        }
        catch (Exception ex)
        {
            mux.ReleaseMutex();
            CoreEvent cevent = new CoreEvent();
            cevent.eventType = NetEventType.SS_SERVER_START_FAILED;
            cevent.log = ex.Message;
            NetCore.AddEvent(cevent);
            return false;
        }
    }

    /// <summary>
    /// 关闭服务器
    /// </summary>
    public void CloseServer()
    {

        mux.WaitOne();
        isRun = false;
        if (tcpServer == null)
        {
            mux.ReleaseMutex();
            return;
        }
        tcpServer.Close();
        
        for (int i = 0; i < allClients.Count; i++)
        {
            allClients[i].Close();
        }
        allClients.Clear();
        //Debug.Log("ClientProxy 数量:" + allClients.Count);
 
        tcpServer = null;
        mux.ReleaseMutex();
        CoreEvent ce = new CoreEvent();
        ce.eventType = NetEventType.SS_CLOSE_SERVER;
        ce.log = string.Format("[{0}:{1}]服务器关闭成功!", ip, port);
        NetCore.AddEvent(ce);
        return;
    }


    public void RemoveClient(NetEventType type, string log, ClientBase sender)
    {
        CoreEvent ce = new CoreEvent();
        
        mux.WaitOne();
        if (allClients.Contains(sender))
        {
            ce.eventType = type;
            ce.sender = sender;
            ce.log = log;
            NetCore.AddEvent(ce);
            allClients.Remove(sender);
            
        }
        else
        {
            ce.eventType = NetEventType.SS_REMOVE_CLIENT_FAILED;
            ce.sender = sender;
            ce.log = log;
            NetCore.AddEvent(ce);
        }
        mux.ReleaseMutex();
    }

    #region 客户端连接
    private void AcceptCb(IAsyncResult ar)
    {
        //当前线程会在服务器关闭的时候调用
        //当服务器已经关闭不进行处理
        if (!isRun) return;
        mux.WaitOne();
        try
        {
            Socket sock = tcpServer.EndAccept(ar);
            //Debug.Log("有客户端连接");
            ClientBase cp = new ClientProxy(sock, this, isPacketDecode);
            allClients.Add(cp);
            tcpServer.BeginAccept(AcceptCb, null);
            mux.ReleaseMutex();
            CoreEvent ce = new CoreEvent();
            ce.eventType = NetEventType.SS_CLIENT_CONNECT_SUCCESS;
            ce.sender = cp;
            NetCore.AddEvent(ce);  
        }
        catch (Exception ex)
        {
            mux.ReleaseMutex();
            CoreEvent ce = new CoreEvent();
            ce.eventType = NetEventType.SS_CLIENT_CONNECT_FAILED;
            ce.log = ex.Message;
            NetCore.AddEvent(ce);
        }

    }
    #endregion

    public void BroadCastMessage(byte[] msg)
    {
        for (int i = 0; i < allClients.Count; i++)
        {
            allClients[i].Send(msg);
        }
    }
}
